<template>
  <div class="overflow-x-auto">
    <table :class="cn(tableVariants({ modifier, size }))">
      <thead>
        <tr>
          <th v-for="column in columns" :key="column.name">
            {{ column.label }}
          </th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="row in data" :key="row[keyName]">
          <td
            class="text-ellipsis overflow-hidden whitespace-nowrap"
            v-for="column in columns"
            :key="column.name"
          >
            <slot :name="column.name" :row="row">
              {{ formatCell(row, column) }}
            </slot>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>
<script
  setup
  lang="ts"
  generic="T extends Record<string, any>, K extends keyof T"
>
import { cva } from "class-variance-authority";
import { formatDate } from "@vueuse/core";
import { cn } from "../utils";
import type { TableModifier, Size } from "./types";

export interface TableColumn {
  name: string;
  label: string;
  type?: "date" | "datetime";
}

interface Props {
  data: T[];
  columns: TableColumn[];
  keyName: K;
  modifier?: TableModifier;
  size?: Size;
}
defineProps<Props>();
const tableVariants = cva("table", {
  variants: {
    modifier: {
      zebra: "table-zebra",
      "pin-rows": "table-pin-rows",
      "pin-cols": "table-pin-cols",
    },
    size: {
      xs: "table-xs",
      sm: "table-sm",
      md: "table-md",
      lg: "table-lg",
      xl: "table-xl",
    },
  },
});

function formatCell(row: T, column: TableColumn) {
  if (column.type == null) return row[column.name];
  return column.type == "date"
    ? formatDate(new Date(row[column.name]), "YYYY-MM-DD")
    : formatDate(new Date(row[column.name]), "YYYY-MM-DD HH:mm:ss");
}
</script>
